home *** CD-ROM | disk | FTP | other *** search
- /*{{{}}}*/
- /*{{{ includes*/
- #ifdef CONFIG_H
- # include "config.h"
- #endif
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <ctype.h>
- #include <unistd.h>
- #include <string.h>
- #include <limits.h>
-
- #define I_DISPLAY_C
- #define I_GETTK_C
- #define I_MAIN_C
- #define I_SCREEN_C
- #define I_SIGNALS_C
- #define SCRBUFF_C
-
- #include "origami.h"
- #include <lib/ori_add_lib.h>
- #include <h/envvar_str.h>
- /*}}} */
-
- /*{{{ types*/
- /*{{{ pentype*/
- #define PEN_MASK (~(O_NOP-1))
- typedef enum { NORM=0,HIGHLIGHT=O_NOP,SG_SPACE=PEN_MASK } pentype;
- /*}}} */
- /*{{{ c_p_type - coding pen and character*/
- #define c_p_code_gen(c,p) ((c)|(p))
-
- typedef enum
- { SPACE_CODE=c_p_code_gen(' ',NORM),
- SO_CODE =c_p_code_gen('@',SG_SPACE),
- SE_CODE =c_p_code_gen('$',SG_SPACE)
- } c_p_code;
-
- #define B_code_c_p(c,p) ((c_p_code)c_p_code_gen(c,p))
- #define B_get_pen(c) ((c)&PEN_MASK)
- #define B_get_char(c) ((c)&(~(PEN_MASK)))
- #define B_test_pen(c,p) (B_get_pen(c)==(p))
- /*}}} */
- /*{{{ chg_type - how is a line changed*/
- typedef enum { OK=0,CHANGED,INVALID } chg_type;
- /*}}} */
-
- typedef struct
- { c_p_code *code; /* char and pen data */
- chg_type mode; /* changed? */
- int id; /* line number on old screen */
- } linebuffer;
- /*}}} */
- /*{{{ variables*/
- private linebuffer *B_scr_data=0; /* malloced space for 2 buffers */
-
- private boolean B_buf_id; /* tag for current of 2 buffers */
- private linebuffer *B_current_scr=0;/* Pointer to current screen buffer */
-
- private c_p_code *B_empty_line; /* screen.w sized array with SPACE_CODE */
- private c_p_code *B_buff_line; /* screen.w sized array */
-
- private linebuffer *B_cur_line; /* pointer to current line in buffer */
-
- private win_data B_pos={0,0}; /* buffer cursor */
- private pentype B_pen; /* current pen */
-
- private boolean B_clr_scr_used=True;/* should ClrScr used first on flush */
- private int B_new_line; /* no of deleted/scrolled out lines */
- private boolean B_use_dl_al; /* should next flush use il/al */
- private chg_type B_scr_mode; /* do a full redraw at next flush */
- private boolean B_check_so_glitch; /* any standout glitch to be handled */
-
- private boolean B_do_buffer=False; /* is terminal initialised */
- private boolean B_active=False; /* buffered termout active */
- /*}}} */
-
- /*{{{ screen handling*/
- private win_data scr_pos={ 0,0 };
- /*{{{ S_invalid_pos*/
- #define S_invalid_pos() (scr_pos.h=0)
- /*}}} */
- /*{{{ S_shift_pos*/
- #define S_shift_pos(x) \
- do { if ((scr_pos.w+=x)>screen.w) S_invalid_pos(); } while (NEVER)
- /*}}} */
- /*{{{ S_step_or_move*/
- private void S_step_or_move(int y,int x)
- {
- if (scr_pos.h==0)
- move_cursor_to(y,x);
- else if (scr_pos.h!=y || scr_pos.w!=x)
- step_or_move_cursor(y,x,y-scr_pos.h,x-scr_pos.w);
- else
- return;
- scr_pos.h=y;
- scr_pos.w=x;
- }
- /*}}} */
- /*{{{ S_moveclreol*/
- #define S_moveclreol(y,x) (moveclreol((y),(x)),S_invalid_pos())
- /*}}} */
- /*{{{ S_ClrScr*/
- #define S_ClrScr() (ClrScr(),S_invalid_pos())
- /*}}} */
- /*}}} */
- /*{{{ internal buffer handling procedures*/
- /*{{{ B_check_active*/
- #define B_check_active() (redraw_on_sig=!(B_active=B_do_buffer&&B_scr_data))
- /*}}} */
-
- /*{{{ B_get_start*/
- #define B_get_start(i) (B_current_scr=B_scr_data-1+((i)?screen.h:0))
- /*}}} */
- /*{{{ B_toggle_start*/
- #define B_toggle_start() B_get_start(B_buf_id= !B_buf_id)
- /*}}} */
-
- /*{{{ B_check_h_position*/
- #define B_check_h_pos(ph) \
- do{if((ph)<=0)(ph)=1;else if((ph)>screen.h)(ph)=screen.h;}while(NEVER)
- /*}}} */
- /*{{{ B_check_high_w_position*/
- #define B_check_high_w_pos(pw) \
- do{if((pw)>screen.w)(pw)=screen.w;}while(NEVER)
- /*}}} */
- /*{{{ B_check_w_position*/
- #define B_check_w_pos(pw) \
- do{if((pw)<=0)(pw)=1;else B_check_high_w_pos(pw);}while(NEVER)
- /*}}} */
- /*{{{ B_check_position*/
- #define B_check_pos(ph,pw) \
- do{B_check_h_pos(ph);B_check_w_pos(pw);}while(NEVER)
- /*}}} */
- /*{{{ B_inc_w_position*/
- #define B_inc_w_position(p) do{if(++(p)>screen.w)(p)=screen.w;}while(NEVER)
- /*}}} */
- /*{{{ B_update_line_pointer*/
- #define B_update_line_pointer() (B_cur_line=B_current_scr+B_pos.h)
- /*}}} */
-
- /*{{{ B_check_cursor*/
- private void B_check_cursor(void)
- {
- B_check_pos(B_pos.h,B_pos.w);
- B_update_line_pointer();
- }
- /*}}} */
-
- /*{{{ B_copy*/
- #define B_copy(d,s,l) memcpy((d),(s),(l)*sizeof(c_p_code))
- /*}}} */
- /*{{{ B_cmp*/
- #define B_cmp(s1,s2,l) memcmp((s1),(s2),(l)*sizeof(c_p_code))
- /*}}} */
- /*{{{ B_clr*/
- #define B_clr(l,f,t) B_copy((l)+(f),B_empty_line,(t)-(f)+1)
- /*}}} */
-
- /*{{{ B_al_dl_rotate*/
- private void B_al_dl_rotate(int from,int to)
- {
- linebuffer c;
- int diff;
-
- c=B_current_scr[from];
- for (diff=(from<=to)?1:-1;from!=to;from+=diff)
- B_current_scr[from]=B_current_scr[from+diff];
- if (c.id)
- { B_new_line++;
- c.id=0;
- }
- c.mode=CHANGED;
- B_current_scr[to]=c;
- }
- /*}}} */
- /*}}} */
-
- /*{{{ B_oputc*/
- public void B_oputc(int c)
- {
- if (!scr_off)
- if (B_active)
- { if (c=='~' && hz)
- { B_oputc(CTRL_MARK);
- c=HZ_TILDE;
- }
- B_cur_line->code[B_pos.w]=B_code_c_p(c,B_pen);
- B_inc_w_position(B_pos.w);
- B_cur_line->mode=CHANGED;
- }
- else
- oputc(c);
- }
- /*}}} */
- /*{{{ B_oputs*/
- public void B_oputs(unsigned char*s)
- {
- if (!scr_off)
- if (B_active)
- { B_cur_line->mode=CHANGED;
- for (;;s++)
- { unsigned char c;
- switch ((c= *s))
- { case '~':
- if (hz)
- { B_cur_line->code[B_pos.w]=B_code_c_p(CTRL_MARK,B_pen);
- B_inc_w_position(B_pos.w);
- c=HZ_TILDE;
- }
- default:
- B_cur_line->code[B_pos.w]=B_code_c_p(c,B_pen);
- B_inc_w_position(B_pos.w);
- continue;
- case '\0':
- break;
- }
- break;
-
- }
- }
- else
- oputs(s);
- }
- /*}}} */
- /*{{{ B_move_cursor_to*/
- public void B_move_cursor_to(int y,int x)
- {
- if (!scr_off)
- if (B_active)
- { B_pos.h=y;
- B_pos.w=x;
- B_check_cursor();
- }
- else
- move_cursor_to(y,x);
- }
- /*}}} */
- /*{{{ B_moveclreol*/
- public void B_moveclreol(int y,int x)
- {
- if (!scr_off)
- if (B_active)
- { B_move_cursor_to(y,x);
- B_cur_line->mode=CHANGED;
- B_clr(B_cur_line->code,B_pos.w,screen.w);
- }
- else
- moveclreol(y,x);
- }
- /*}}} */
- /*{{{ B_ClrScr*/
- public void B_ClrScr(void)
- {
- B_clr_scr_used=True;
- if (!scr_off)
- if (B_active)
- { int l;
-
- for (l=screen.h;l;B_moveclreol(l--,1));
- }
- else
- ClrScr();
- }
- /*}}} */
- /*{{{ B_insLine*/
- public boolean B_insLine(int n)
- {
- if (B_active)
- { if (!scr_off)
- while (n-->0)
- { B_al_dl_rotate(screen.h,B_pos.h);
- B_clr(B_current_scr[B_pos.h].code,1,screen.w);
- }
- return(False);
- }
- else
- return(n!=1 || insLine(1));
- }
- /*}}} */
- /*{{{ B_DelLine*/
- public boolean B_DelLine(int n)
- {
- if (B_active)
- { if (!scr_off)
- while (n-->0)
- { B_al_dl_rotate(B_pos.h,screen.h);
- B_clr(B_current_scr[screen.h].code,1,screen.w);
- }
- return(False);
- }
- else
- return(n!=1 || DelLine(1));
- }
- /*}}} */
- /*{{{ B_scroll_region*/
- /*{{{ B_rotate*/
- private void B_rotate(int y1,int x1,int y2,int x2,boolean up)
- {
- int l;
-
- /* no full check for valid edges! */
- if ((l=x2-x1+1))
- { int from,to,diff;
-
- /*{{{ prepare loop variables*/
- if (up)
- { from=y1;to=y2;diff= 1; }
- else
- { from=y2;to=y1;diff= -1; }
- /*}}} */
- /*{{{ save scrolled out on buffer line*/
- B_copy(B_buff_line,B_current_scr[from].code+x1,l);
- /*}}} */
- /*{{{ shift up/down*/
- for (;from!=to;from+=diff)
- { B_current_scr[from].mode=CHANGED;
- B_copy
- ( B_current_scr[from].code+x1,
- B_current_scr[from+diff].code+x1,
- l
- );
- }
- /*}}} */
- /*{{{ put saved text back again*/
- B_current_scr[to].mode=CHANGED;
- B_copy(B_current_scr[from].code+x1,B_buff_line,l);
- /*}}} */
- }
- }
- /*}}} */
-
- public boolean B_scroll_region(int y1,int x1,int y2,int x2,boolean up)
- {
- if (!scr_off)
- if (B_active)
- /*{{{ scroll in buffer*/
- { B_check_pos(y1,x1);
- B_check_pos(y2,x2);
- /*{{{ maybe change y*/
- if (y1>y2)
- { int l;
-
- l=y1;
- y1=y2;
- y2=l;
- }
- /*}}} */
- /*{{{ maybe change x*/
- if (x1>x2)
- { int l;
-
- l=x1;
- x1=x2;
- x2=l;
- }
- /*}}} */
- if (y1!=y2)
- /*{{{ do the scrolling*/
- {
- /*{{{ rotate*/
- if
- ( SCROLL_INVERSE(x2-x1,screen.w)
- # ifdef BLOCK_FLUSH
- && (x1==1 || x2==screen.w)
- # endif
- )
- /*{{{ scroll using al/dl*/
- {
- /*{{{ rotate all lines in region*/
- if (up)
- B_al_dl_rotate(y1,y2);
- else
- B_al_dl_rotate(y2,y1);
- /*}}} */
- /*{{{ maybe rotate remaining screen parts back in buffer!*/
- if (x1!=1)
- B_rotate(y1,1,y2,x1-1,!up);
- if (x2!=screen.w)
- B_rotate(y1,x2+1,y2,screen.w,!up);
- /*}}} */
- }
- /*}}} */
- else
- /*{{{ scroll in buffer*/
- B_rotate(y1,x1,y2,x2,up);
- /*}}} */
- /*}}} */
- /*{{{ clear part of moved line*/
- B_clr(B_current_scr[up?y2:y1].code,x1,x2);
- /*}}} */
- }
- /*}}} */
- return(False);
- }
- /*}}} */
- return(True);
- }
- /*}}} */
-
- /*{{{ B_invalid*/
- public void B_invalid(void)
- {
- B_scr_mode=INVALID;
- }
- /*}}} */
- /*{{{ B_valid*/
- public void B_valid(void)
- {
- int y;
-
- B_scr_mode=OK;
- B_clr_scr_used=False;
- for (y=screen.h;y;B_current_scr[y--].mode=OK);
- }
- /*}}} */
- /*{{{ B_oflush*/
- /*{{{ cursor_hide/push_position*/
- private boolean cursor_hidden=False;
- private win_data save_cursor_pos;
- /*{{{ csr_push_pos*/
- #define csr_push_pos() (save_cursor_pos=B_pos)
- /*}}} */
- /*{{{ csr_pop_pos*/
- #define csr_pop_pos() \
- while (scr_pos.w!=save_cursor_pos.w || scr_pos.h!=save_cursor_pos.h) \
- { B_pos=save_cursor_pos; \
- redraw_on_sig=True; \
- S_step_or_move(save_cursor_pos.h,save_cursor_pos.w); \
- redraw_on_sig=False; \
- break; \
- }
- /*}}} */
- /*{{{ csr_hide*/
- #define csr_hide() \
- while (!cursor_hidden) \
- { cursor_hidden=True; \
- redraw_on_sig=True; \
- scr_cursor(False); \
- redraw_on_sig=False; \
- break; \
- }
- /*}}} */
- /*{{{ csr_no_hide*/
- #define csr_no_hide() \
- while (cursor_hidden) \
- { redraw_on_sig=True; \
- scr_cursor(True); \
- redraw_on_sig=False; \
- break; \
- }
- /*}}} */
- /*}}} */
- /*{{{ fl_upd_line*/
- #ifndef fl_overwrite
- /*{{{ fl_toggle_pen*/
- private void fl_toggle_pen(pentype *p)
- {
- if (sg) S_invalid_pos();
- if (*p==NORM)
- { do_standout();
- *p=HIGHLIGHT;
- }
- else
- { do_standend();
- *p=NORM;
- }
- }
- /*}}} */
- #endif
- #ifndef BLOCK_FLUSH
- /*{{{ fl_test_shift*/
- private int fl_test_shift
- ( const c_p_code *left,
- const c_p_code *right,
- const int to,
- const int max
- )
- { int l;
-
- for (left-=(l=1);l<=max;l++,left--)
- if (l)
- { int i;
-
- for (i=l;;i++)
- if (i>to)
- return(l);
- else if (left[i]!=right[i])
- break;
- }
- return(0);
- }
- /*}}} */
- /*{{{ fl_m_insert*/
- private void fl_m_insert(const c_p_code *s, int lg)
- { int l;
- pentype p;
- unsigned char buff[FL_SHIFT_MAX];
-
- for (l=0,p=NORM;lg--;)
- /*{{{ move chars in buffer*/
- { c_p_code c;
-
- c= *s++;
- if (B_get_pen(c)!=p)
- /*{{{ change pen*/
- { if (l)
- /*{{{ print old*/
- { insChar(buff,l);
- S_shift_pos(l);
- l=0;
- }
- /*}}} */
- fl_toggle_pen(&p);
- }
- /*}}} */
- /*{{{ store char in buff*/
- buff[l++]=B_get_char(c);
- /*}}} */
- }
- /*}}} */
- if (l)
- /*{{{ print missing chars*/
- { insChar(buff,l);
- S_shift_pos(l);
- }
- /*}}} */
- if (p!=NORM)
- fl_toggle_pen(&p);
- }
- /*}}} */
- #endif
- #ifndef fl_overwrite /* can be defined for special window systems ! */
- /*{{{ fl_overwrite*/
- /*{{{ buffered output for chars*/
- # ifdef BLOCK_FLUSH
- /*{{{ direct print, no buffering*/
- # define over_init()
- # define over_flush()
- # define over_put(c) oputc(c)
- /*}}} */
- # else
- private int n_buff;
- private unsigned char c_buff;
- private boolean skip_right;
- /*{{{ over_init*/
- # define over_init() (c_buff=skip_right=n_buff=0)
- /*}}} */
- /*{{{ over_flush*/
- private void over_fl_int(void)
- {
- if (skip_right)
- { step_or_move_cursor(scr_pos.h,scr_pos.w-n_buff,0,skip_right);
- S_shift_pos(n_buff-1);
- skip_right=0;
- }
- skip_right+=moputc(c_buff,n_buff);
- n_buff=0;
- }
- # define over_flush() (n_buff?over_fl_int():(void)0)
- /*}}} */
- /*{{{ over_skip*/
- # define over_skip(w) (over_flush(),skip_right+=(w))
- /*}}} */
- /*{{{ over_put*/
- # define over_put(ch) \
- (((ch)==c_buff)?n_buff++:(over_flush(),c_buff=(ch),n_buff=1))
- /*}}} */
- # endif
- /*}}} */
-
- private void fl_overwrite
- ( int y,
- int from_txt,
- int to_txt,
- int end_space,
- const c_p_code *cnew
- # ifndef BLOCK_FLUSH
- ,const c_p_code *cold
- # endif
- )
- {
- /*{{{ variables*/
- int x;
- int to_over;
- pentype fl_pen;
- /*}}} */
-
- over_init();
- /*{{{ maybe disable skiping equal parts*/
- # ifndef BLOCK_FLUSH
- if (to_txt-from_txt<=FL_SHIFT_OVER)
- cold=0;
- # endif
- /*}}} */
- /*{{{ maybe use clear_to_end_of_line*/
- if (end_space<=to_txt)
- to_over=end_space-1;
- else
- { to_over=to_txt;
- end_space=0;
- }
- /*}}} */
- S_step_or_move(y,from_txt);
- for (x=from_txt,fl_pen=NORM;x<=to_over;x++)
- /*{{{ print the charater*/
- { int c;
-
- c=cnew[x];
- /*{{{ maybe switch to other pen (sg-chars also switch)*/
- if (B_get_pen(c)!=fl_pen)
- { over_flush();
- fl_toggle_pen(&fl_pen);
- }
- if (B_test_pen(c,SG_SPACE))
- /*{{{ skip the used area, do not print the garbage*/
- { x+=sg-1;
- continue;
- }
- /*}}} */
- /*}}} */
- c=B_get_char(c);
- over_put((unsigned char)c);
- S_shift_pos(1);
- # ifndef BLOCK_FLUSH
- /*{{{ check skip over equal parts*/
- if (cold && (mi || fl_pen==NORM))
- { int l;
-
- for (l=x+1;l<=to_over;)
- if ((c=cnew[l])!=cold[l] || (!mi && !B_test_pen(c,NORM)) )
- break;
- else
- l++;
- l-=x+1;
- if (l>=FL_SHIFT_OVER)
- { x+=l;
- over_skip(l);
- continue;
- }
- }
- /*}}} */
- # endif
- }
- /*}}} */
- over_flush();
- /*{{{ maybe reset pen*/
- if (fl_pen!=NORM)
- fl_toggle_pen(&fl_pen);
- /*}}} */
- /*{{{ maybe clear rest of line*/
- if (end_space)
- S_moveclreol(y,end_space);
- /*}}} */
- }
- /*}}} */
- #else
- # include "os_scrbuff.c"
- #endif
-
- private void fl_upd_line
- ( int y,
- c_p_code * const cold,
- const c_p_code * const cnew,
- boolean full
- )
- {
- /*{{{ variables*/
- int from_txt,to_txt,end_space;
- # ifndef BLOCK_FLUSH
- boolean no_shift;
- # endif
- /*}}} */
-
- /*{{{ get redraw part of line*/
- /*{{{ init whole line*/
- from_txt=1;
- to_txt=screen.w;
- /*}}} */
- if (!full)
- /*{{{ try to reduce diff part to a inner block*/
- {
- /*{{{ skip equal part at start*/
- for (;;)
- if (cnew[from_txt]!=cold[from_txt])
- break;
- else if (from_txt==screen.w)
- return;
- else
- from_txt++;
- /*}}} */
- /*{{{ skip equal part at end*/
- for (;;)
- if (cnew[to_txt]!=cold[to_txt])
- break;
- else
- to_txt--;
- /*}}} */
- }
- /*}}} */
- if (am && y==screen.h && to_txt==screen.w)
- to_txt--;
- /*}}} */
- /*{{{ get whitespace section at end of line*/
- if (ce)
- { for (end_space=screen.w;;)
- if (cnew[end_space]!=SPACE_CODE)
- break;
- else if (--end_space==0)
- break;
- end_space++;
- }
- else
- end_space=screen.w+1;
- /*}}} */
- /*{{{ check glitches*/
- # ifndef BLOCK_FLUSH
- no_shift=!use_shift || B_scr_mode;
- # endif
- if (!full && B_check_so_glitch)
- { int up;
- int to;
-
- for (up=1,to=screen.w;;)
- if (B_test_pen(cnew[up],NORM) && B_test_pen(cold[up],NORM))
- /*{{{ next char or end search*/
- if (up==to)
- break;
- else
- up++;
- /*}}} */
- else
- /*{{{ sorry, but must handle the so glitch :-(*/
- { if (xs)
- /*{{{ use clear-to-end-of-line*/
- S_moveclreol(y,1);
- /*}}} */
- if (xt)
- /*{{{ use al/dl to get rid of the so*/
- { redraw_on_sig=True;
- S_step_or_move(y,1);
- DelLine(1);
- S_step_or_move(y,1);
- insLine(1);
- redraw_on_sig=False;
- B_move_cursor_to(y,1);
- B_DelLine(1);
- B_move_cursor_to(y,1);
- B_insLine(1);
- }
- /*}}} */
- /*{{{ complete line without shifting*/
- from_txt=1;
- to_txt=screen.w;
- # ifndef BLOCK_FLUSH
- no_shift=True;
- # endif
- /*}}} */
- break;
- }
- /*}}} */
- }
- /*}}} */
- csr_hide();
- /*{{{ update the line*/
- {
- # ifndef BLOCK_FLUSH
- int shift;
-
- /*{{{ get shift width*/
- switch (no_shift)
- { case False:
- { int l1,l2;
-
- l1=to_txt-from_txt;
- l2=(l1+1)/FL_SHIFT_SCALE;
- if (l2)
- { if (l2>FL_SHIFT_MAX)
- l2=FL_SHIFT_MAX;
- shift=fl_test_shift(cold+from_txt,cnew+from_txt,l1,l2);
- if (shift==0)
- shift= -fl_test_shift(cnew+from_txt,cold+from_txt,l1,l2);
- break;
- }
- }
- default:
- shift=0;
- }
- /*}}} */
- redraw_on_sig=True;
- if (shift>0)
- /*{{{ maybe shift right*/
- { if (to_txt<screen.w)
- /*{{{ move and delete*/
- { S_step_or_move(y,to_txt-shift+1);
- delChar(shift);
- }
- /*}}} */
- S_step_or_move(y,from_txt);
- fl_m_insert(cnew+from_txt,shift);
- }
- /*}}} */
- else if (shift<0)
- /*{{{ maybe shift left*/
- { S_step_or_move(y,from_txt);
- delChar(-shift);
- if (shift!=-1 || cnew[to_txt]!=SPACE_CODE || to_txt!=end_space)
- /*{{{ insert the chars*/
- { S_step_or_move(y,to_txt+shift+1);
- fl_m_insert(cnew+to_txt+shift+1,-shift);
- }
- /*}}} */
- }
- /*}}} */
- else
- # else
- redraw_on_sig=True;
- # endif
- fl_overwrite
- ( y,
- from_txt,
- to_txt,
- end_space,
- cnew
- # ifndef BLOCK_FLUSH
- ,(full && B_scr_mode==OK)?cold:0
- # endif
- );
- redraw_on_sig=False;
- /*{{{ copy new to old*/
- B_copy(cold+from_txt,cnew+from_txt,to_txt-from_txt+1);
- /*}}} */
- }
- /*}}} */
- }
- /*}}} */
-
- public void B_oflush(void)
- {
- if (!scr_off)
- { if (B_active)
- /*{{{ buffer update*/
- do
- {
- /*{{{ variables*/
- linebuffer *new;
- linebuffer *old;
- /*}}} */
-
- csr_push_pos();
- /*{{{ maybe handle signal flush*/
- if (interrupt_restore)
- { B_clr_scr_used=True;
- interrupt_restore=False;
- }
- /*}}} */
- /*{{{ set new/old to both buffers and change buffers*/
- new=B_current_scr;
- B_toggle_start();
- old=B_current_scr;
- B_update_line_pointer();
- /*}}} */
- /*{{{ check invalid screen/dl_al usage*/
- if (B_clr_scr_used)
- B_scr_mode=INVALID;
- else if (B_use_dl_al)
- if (FL_NO_DL_AL(B_new_line,screen.h))
- B_use_dl_al=False;
- else if (B_scr_mode!=OK)
- B_use_dl_al=False;
- /*}}} */
- /*{{{ maybe do clrscr first!*/
- if (B_clr_scr_used)
- { csr_hide();
- redraw_on_sig=True;
- S_ClrScr();
- redraw_on_sig=False;
- B_clr_scr_used=False;
- }
- /*}}} */
- /*{{{ update lines*/
- { int first_diff;
- int first_upd;
- boolean d,a;
- int m_add;
-
- for
- ( m_add=1,
- first_upd=1,
- a=d=B_use_dl_al,
- first_diff=1+(B_use_dl_al ? 0 : screen.h)
- ; first_upd<=screen.h && !interrupt_restore
- ;
- )
- {
- /*{{{ update all correct scrolled lines*/
- { linebuffer *op,*np;
-
- for
- ( op=old+first_upd,np=new+first_upd
- ; first_upd<first_diff
- ; op++,np++,first_upd++
- )
- { if
- ( np->mode!=OK
- || np->id!=op->id
- || B_scr_mode!=OK
- )
- fl_upd_line
- ( first_upd,
- op->code,
- np->code,
- B_scr_mode!=OK
- );
- op->mode=OK;
- op->id=np->id=first_upd;
- }
- }
- /*}}} */
- /*{{{ try to delete a line*/
- if (d)
- { int yo,yn;
-
- for (yn=yo=first_diff,d=False;yn<=screen.h;)
- { int idn;
-
- if (old[yo].id==(idn=new[yn].id))
- /*{{{ next(new,old), maybe inc correct shifted part*/
- { if (yo==first_diff && yn==first_diff)
- first_diff++;
- yo+=1;
- yn+=1;
- }
- /*}}} */
- else if (idn==0)
- /*{{{ next new*/
- yn++;
- /*}}} */
- else
- /*{{{ do a dl*/
- { int n;
-
- /*{{{ get number of delete lines*/
- { int ido;
- int ys;
-
- for
- ( n=1
- ; (ys=yo+n)<=screen.h && (ido=old[ys].id) && ido!=idn
- ; n++
- );
- if (n>FL_MAX_AL_DL)
- n=FL_MAX_AL_DL;
- m_add+=n-1;
- }
- /*}}} */
- csr_hide();
- redraw_on_sig=True;
- S_step_or_move(yo,1);
- DelLine(n);
- redraw_on_sig=False;
- B_move_cursor_to(yo,1);
- while (n--)
- B_DelLine(1);
- d=True;
- break;
- }
- /*}}} */
- }
- /*{{{ no more deletes, so adds are allowed unlimited*/
- if (!d)
- m_add=screen.h;
- /*}}} */
- }
- /*}}} */
- /*{{{ try to add a line*/
- if (a)
- { int yo,yn;
-
- for (yo=yn=first_diff,a=False;yo<=screen.h;)
- { int ido,idn;
-
- if ((ido=old[yo].id)==(idn=new[yn].id))
- /*{{{ next(new,old), maybe inc correct shifted part*/
- { if (yo==first_diff && yn==first_diff)
- first_diff++;
- yo+=1;
- yn+=1;
- }
- /*}}} */
- else if (ido<idn)
- /*{{{ next old*/
- yo++;
- /*}}} */
- else
- /*{{{ do a al*/
- { int n;
-
- /*{{{ get number of add lines*/
- { int ys;
-
- for (n=1;(ys=yn+n)<=screen.h && new[ys].id==0;n++);
- /*{{{ limit #, to prevent scroll out*/
- if (n>m_add)
- { n=m_add;
- m_add=0;
- }
- else
- m_add-=n;
- /*}}} */
- }
- /*}}} */
- csr_hide();
- redraw_on_sig=True;
- S_step_or_move(yo,1);
- insLine(n);
- redraw_on_sig=False;
- B_move_cursor_to(yo,1);
- while (n--)
- B_insLine(1);
- a=True;
- break;
- }
- /*}}} */
- }
- }
- /*}}} */
- }
- }
- /*}}} */
- /*{{{ restore and show cursor*/
- csr_pop_pos();
- csr_no_hide();
- /*}}} */
- /*{{{ screen is now up to date*/
- B_scr_mode=OK;
- B_use_dl_al=al&&dl;
- B_new_line=0;
- /*}}} */
- }
- while (interrupt_restore);
- /*}}} */
- oflush;
- }
- }
- /*}}} */
-
- /*{{{ B_do_standout/end*/
- /*{{{ B_sg*/
- private void B_sg(int i,c_p_code c)
- {
- do
- { B_cur_line->code[B_pos.w]=c;
- B_inc_w_position(B_pos.w);
- }
- while (--i);
- }
- /*}}} */
- /*{{{ B_do_standout*/
- public void B_do_standout(void)
- {
- if (so)
- { B_pen=HIGHLIGHT;
- if (B_active)
- { if (sg)
- B_sg(sg,SO_CODE);
- }
- else
- do_standout();
- }
- }
- /*}}} */
- /*{{{ B_do_standend*/
- public void B_do_standend(void)
- {
- if (so)
- { B_pen=NORM;
- if (B_active)
- { if (sg)
- B_sg(sg,SE_CODE);
- }
- else
- do_standend();
- }
- }
- /*}}} */
- /*}}} */
- /*{{{ B_init_terminal*/
- public void B_init_terminal(void)
- {
- init_terminal();
- S_invalid_pos();
- B_do_buffer=True;
- B_scr_mode=INVALID;
- B_clr_scr_used=True;
- B_check_active();
- }
- /*}}} */
- /*{{{ B_reset_terminal*/
- public void B_reset_terminal(void)
- {
- B_oflush();
- S_invalid_pos();
- reset_terminal();
- B_do_buffer=False;
- B_check_active();
- }
- /*}}} */
-
- /*{{{ B_get_terminal_capability*/
- public int B_get_terminal_capability(void)
- {
- int x;
- win_data old_screen;
-
- /*{{{ get old size of the screen, or dummy value*/
- if (B_scr_data && B_do_buffer)
- old_screen=screen;
- else
- old_screen.h= -1;
- /*}}} */
- if ((x=get_terminal_capability()))
- return(x);
- if ((old_screen.h!=screen.h) || (old_screen.w!=screen.w))
- /*{{{ changed sizes, so new buffer*/
- { if (B_scr_data)
- paket_free(B_scr_data);
- if
- /*{{{ can malloc space for 2 buffers*/
- ((B_scr_data=
- paket_malloc
- ( 2*screen.w*sizeof(c_p_code) /* empty and buffer line */
- + 2 * screen.h /* 2 buffer: */
- * ( sizeof(linebuffer) /* line descriptor */
- + screen.w*sizeof(c_p_code) /* text field */
- )
- )
- ))
- /*}}} */
- /*{{{ start up buffering*/
- { B_get_start(B_buf_id=False);
- /*{{{ init empty and buff line*/
- B_empty_line=(c_p_code*)((linebuffer*)B_scr_data+2*screen.h);
- for
- ( B_buff_line=B_empty_line,x=screen.w
- ; x--
- ; *B_buff_line++=SPACE_CODE
- );
- /*}}} */
- /*{{{ set up each line buffer*/
- { c_p_code *s;
- linebuffer *l;
-
- for
- ( l=B_scr_data,x=2*screen.h,s=B_buff_line+screen.w
- ; x
- ; x--,l++,s+=screen.w
- )
- { l->mode=OK;
- if ((l->id=(l-B_scr_data+1))>screen.h)
- l->id-=screen.h;
- B_clr(l->code=s-1,1,screen.w);
- }
- }
- /*}}} */
- /*{{{ empty screen, cursor at 1/1*/
- B_move_cursor_to(1,1);
- S_ClrScr();
- B_valid();
- B_use_dl_al=al&&dl;
- B_new_line=0;
- /*}}} */
- }
- /*}}} */
- }
- /*}}} */
- B_check_active();
- if (B_scr_data)
- { if ((xs && !ce) || (xt && !B_use_dl_al))
- { so=0;
- allow_text_so=False;
- if (dsp.ctrl==ictrl_dsp)
- { dsp.ctrl=mark_dsp;
- dsp.ctrl_add=0;
- }
- }
- B_check_so_glitch=(so && (sg || xs || xt));
- }
- return(0);
- }
- /*}}} */
-
- #ifdef EXT_SCRBUFF_ACCESS
- /*{{{ cur_scr_char*/
- public unsigned char cur_scr_char(int y,int x)
- {
- return
- ( (B_active && x<=screen.w && x>0 && y<=screen.h && y>0)
- ? (unsigned char)B_get_char(B_current_scr[y].code[x])
- : (unsigned char)'\0'
- );
- }
- /*}}} */
- #endif
-